// 
//  JKPlayingViewController.m
//  QQMusic
// 
//  Created by albert on 16/4/7.
//  Copyright (c) 2016年 albert. All rights reserved.
// 

#import "JKPlayingViewController.h"
#import "Masonry.h"
#import "JKAudioTool.h"
#import "JKMusicTool.h"
#import "JKMusicModel.h"
#import <AVFoundation/AVFoundation.h>
#import "CALayer+PauseAimate.h"
#import "NSString+JKTimeExtension.h"
#import "JKLrcScrollView.h"
#import "JKLrcLabel.h"
#import <MediaPlayer/MediaPlayer.h>

#define JKColor(r, g, b) ([UIColor colorWithRed:r/255.0 green:g/255.0 blue:b/255.0 alpha:1.0])

@interface JKPlayingViewController ()<AVAudioPlayerDelegate, UIScrollViewDelegate, UIGestureRecognizerDelegate>
/** 播放器 */
@property (nonatomic, strong) AVAudioPlayer *player;

/** 动画 */
@property (nonatomic, strong) CAKeyframeAnimation *animation;

/** 当前播放的歌曲模型 */
@property (nonatomic, strong) JKMusicModel *playingMusic;

/** 进度的定时器 */
@property (nonatomic, strong) NSTimer *progressTimer;

/** 歌词的定时器 */
@property (nonatomic, strong) CADisplayLink *lrcLink;

/** 显示音量条的view */
@property (nonatomic, weak) UIView *coverView;

/** 系统音量条view */
@property (nonatomic, weak) MPVolumeView *volumeView;

// 播放界面
@property (weak, nonatomic) IBOutlet UIImageView *albumView;
@property (weak, nonatomic) IBOutlet UIImageView *iconView;
@property (weak, nonatomic) IBOutlet UILabel *musicNameLabel;
@property (weak, nonatomic) IBOutlet UILabel *singerLabel;
@property (weak, nonatomic) IBOutlet UILabel *currentTimeLabel;
@property (weak, nonatomic) IBOutlet UILabel *leftTimeLabel;
@property (weak, nonatomic) IBOutlet JKLrcLabel *lrcLabel;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *topViewTopCons;

// 滑块
@property (weak, nonatomic) IBOutlet UISlider *progressSlider;
@property (weak, nonatomic) IBOutlet UIButton *playButton;
@property (weak, nonatomic) IBOutlet UIButton *pauseButton;
@property (weak, nonatomic) IBOutlet JKLrcScrollView *lrcScrollView;
@end

@implementation JKPlayingViewController

- (UIStatusBarStyle)preferredStatusBarStyle{
    return UIStatusBarStyleLightContent;
}

#pragma mark - 懒加载
- (AVAudioPlayer *)player{
    if (_player == nil) {
        _player = [JKAudioTool playerWithMusicName:self.playingMusic.filename];
        _player.delegate = self;
    }
    return _player;
}

- (JKMusicModel *)playingMusic{
    if (_playingMusic == nil) {
        _playingMusic = [JKMusicTool playingMusic];
    }
    return _playingMusic;
}

- (CAKeyframeAnimation *)animation{
    if (!_animation) {
        CAKeyframeAnimation *animation = [CAKeyframeAnimation animation];
        animation.keyPath = @"transform.rotation";
        animation.repeatCount = NSIntegerMax;
        
        animation.values = @[@(0), @(M_PI * 2)];
        
        animation.duration = 15.0;
        _animation = animation;
    }
    return _animation;
}

#pragma mark - 初始化
- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.topViewTopCons.constant = [UIApplication sharedApplication].statusBarFrame.size.height - 20;
    
    /**
     添加毛玻璃效果的三中方式
     - 1.直接来一张毛玻璃效果的图片
     - 2.第三方框架 DRNRealTimeBlur 直接继承自它就有毛玻璃效果
     - 3.CoreImage 图片高斯模糊
     - 4.UIToolBar 本身就是毛玻璃效果
     */
    
    // 1、添加毛玻璃效果
    [self setupBlurView];
    
    // 2、设置滑块的图片
    [self.progressSlider setThumbImage:[UIImage imageNamed:@"player_slider_playback_thumb"] forState:(UIControlStateNormal)];
    
    // 3、设置展示界面的信息
    [self setupPlayingMusic:self.playingMusic];
    
    // 4、进度条添加点击事件
    [self.progressSlider addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(sliderClick:)]];
    
    // 5.添加点击弹出音量条
    [self.lrcScrollView addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(showVolumSlider)]];
}

// 添加点击弹出音量条
- (void)showVolumSlider{
    UIView *coverView = [[UIView alloc] initWithFrame:self.view.bounds];
    coverView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.7];
    [self.view addSubview:coverView];
    _coverView = coverView;
    
    UITapGestureRecognizer *coverTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(removeCoverView)];
    coverTap.delegate = self;
    [coverView addGestureRecognizer:coverTap];
    
    // 音量view
    MPVolumeView *volumeView = [[MPVolumeView alloc] init];
    volumeView.frame = CGRectMake(coverView.frame.size.width * 0.1, coverView.frame.size.height * 0.5, coverView.frame.size.width * 0.8, 30);
    [coverView addSubview:volumeView];
    _volumeView = volumeView;
    
    /* 可以得到音量条
    UISlider* volumeViewSlider = nil;
    for (UIView *view in volumeView.subviews){
        if ([view.class.description isEqualToString:@"MPVolumeSlider"]){
            volumeViewSlider = (UISlider*)view;
            break;
        }
    }*/
}

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer{
    
    CGPoint location = [gestureRecognizer locationInView:gestureRecognizer.view];
    
    CGPoint point = [self.coverView convertPoint:location toView:self.volumeView];
    
    if ([self.volumeView pointInside:point withEvent:nil]) {
        return NO;
    }
    
    return YES;
}

- (void)removeCoverView{
    [self.coverView removeFromSuperview];
}

// 设置展示界面的信息
- (void)setupPlayingMusic:(JKMusicModel *)music{
    self.albumView.image = [UIImage imageNamed:music.icon];
    self.iconView.image = [UIImage imageNamed:music.icon];
    self.musicNameLabel.text = music.name;
    self.singerLabel.text = music.singer;
    
    self.lrcScrollView.lrcName = self.playingMusic.lrcname;
    self.lrcScrollView.duration = self.player.duration;
    
    // 一开始 先清空外面的歌词
    self.lrcLabel.text = @"";
    self.lrcScrollView.lrcLabel = self.lrcLabel;
    
    // 更新进度条
    [self updateProgressInfo];
}

// 在这里添加圆角效果，这里得到的尺寸最真实
- (void)viewWillLayoutSubviews{
    [super viewWillLayoutSubviews];
    
    self.iconView.layer.cornerRadius = self.iconView.frame.size.width * 0.5;
    self.iconView.layer.masksToBounds = YES;
    self.iconView.layer.borderWidth = 8;
    self.iconView.layer.borderColor = JKColor(36, 36, 36).CGColor;
}

// 添加毛玻璃效果
- (void)setupBlurView{
    UIToolbar *toolBar = [[UIToolbar alloc] init];
    // 样式
    toolBar.barStyle = UIBarStyleBlack;
    toolBar.translatesAutoresizingMaskIntoConstraints = NO;
    [self.albumView addSubview:toolBar];
    
    // 添加毛玻璃的约束
    [toolBar mas_makeConstraints:^(MASConstraintMaker *make) {
        make.edges.equalTo(self.albumView);
    }];
}

#pragma mark - 音乐播放
// 点击播放按钮
- (IBAction)startPlayingMusic {
    self.playButton.hidden = YES;
    self.pauseButton.hidden = NO;
    
    // 播放当前音乐
    [self playMusicWithMusic:[JKMusicTool playingMusic]];
}

// 点击暂停按钮
- (IBAction)pause {
    self.pauseButton.hidden = YES;
    self.playButton.hidden = NO;
    
    // 移除定时器
    [self removeProgressTimer];
    [self removeLrcLink];
    
    // 暂停当前播放的音乐
    [JKAudioTool pauseMusicWithMusicName:self.playingMusic.filename];
    
    // 暂停核心动画
    [self.iconView.layer pauseAnimate];
}

// 点击上一首
- (IBAction)previousMuisic {
    self.pauseButton.hidden = NO;
    self.playButton.hidden = YES;
    
    // 播放上一曲
    [self playMusicWithMusic:[JKMusicTool previousMusic]];
}

// 点击下一首
- (IBAction)nextMusic {
    self.pauseButton.hidden = NO;
    self.playButton.hidden = YES;
    
    // 播放下一曲
    [self playMusicWithMusic:[JKMusicTool nextMusic]];
}

// 抽出播放音乐
- (void)playMusicWithMusic:(JKMusicModel *)music{
    
    // 0、先移除之前的定时器，再添加新的定时器
    [self removeProgressTimer];
    [self addProgressTimer];
    
    [self removeLrcLink];
    [self addLrcLink];
    
    // 1、添加动画
    if (self.iconView.layer.animationKeys.count == 0) {
        // 没有动画才添加动画
        [self.iconView.layer addAnimation:self.animation forKey:@"rotation"];
    }
    
    // 2、如果是同一首歌，点击播放，就继续播放并开始动画，直接返回
    if (self.playingMusic == music) {
        [self.player play];
        [self.iconView.layer resumeAnimate];
        return;
    }

    // 3、如果不是同一首歌
    // 3.1 先暂停之前的动画，并移除动画
    [self.iconView.layer pauseAnimate];
    [self.iconView.layer removeAllAnimations];
    // 3.2 将传入的模型参数赋值给要播放的模型
    [JKMusicTool setplayingMusic:music];
    // 3.4 再赋值给属性
    self.playingMusic = [JKMusicTool playingMusic];
    // 3.5 清空播放器。否则会出现一些问题，比如进度条走完不自动下一曲
    self.player = nil;
    
    // 4、设置界面信息
    [self setupPlayingMusic:music];
    
    // 5、开始播放歌曲
    [self.player play];
    
    // 6、处理用户多次点击时的清空
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        
        // 如果音乐和之前的不一样，直接返回
        if (self.playingMusic != music) return;
        
        // 添加动画
        [self.iconView.layer addAnimation:self.animation forKey:@"rotation"];
        
        // 只有是播放状态才开始动画
        if (self.pauseButton.hidden == NO) {
            [self.iconView.layer resumeAnimate];
        }
    });
}

#pragma mark - 对定时器的操作
// 添加进度条定时器
- (void)addProgressTimer{
    self.progressTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(updateProgressInfo) userInfo:nil repeats:YES];
    [[NSRunLoop mainRunLoop] addTimer:self.progressTimer forMode:NSRunLoopCommonModes];
}

// 移除进度条定时器
- (void)removeProgressTimer{
    [self.progressTimer invalidate];
    self.progressTimer = nil;
}

// 添加歌词定时器
- (void)addLrcLink{
    self.lrcLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(updateLrc)];
    [self.lrcLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
}

// 移除歌词定时器
- (void)removeLrcLink{
    [self.lrcLink invalidate];
    self.lrcLink = nil;
}

#pragma mark - 更新进度
- (void)updateProgressInfo{
    // 1、更新两边的时间label
    self.currentTimeLabel.text = [NSString stringWithTime:self.player.currentTime];
    NSTimeInterval leftTime = self.player.duration - self.player.currentTime;
    self.leftTimeLabel.text = [NSString stringWithTime:leftTime];
    
    // 2、更新当前的播放时间
    self.progressSlider.value = self.player.currentTime / self.player.duration;
    [UIView animateWithDuration:0.25 animations:^{
        [self.progressSlider layoutIfNeeded];
    }];
}

#pragma mark - 更新歌词
- (void)updateLrc{
    self.lrcScrollView.currentTime = self.player.currentTime;
}

#pragma mark - 进度条的点击和拖拽
// 开始拖动
- (IBAction)startSlide {
    // 移除定时器
    [self removeProgressTimer];
}

// 值改变
- (IBAction)sliderValueChanged {
    // 设置当前播放时间的label
    self.currentTimeLabel.text = [NSString stringWithTime:self.player.duration * self.progressSlider.value];
    self.leftTimeLabel.text = [NSString stringWithTime:self.player.duration * (1 - self.progressSlider.value)];
    
    // 更新歌词
    [self updateLrc];
}

// 结束拖动
- (IBAction)endSlide {
    // 1、添加timer
    if (self.playButton.hidden == YES) {
        [self addProgressTimer];
    }
    
    // 2、设置歌曲的播放时间
    // 2.1 如果拖动最后面结束位置，直接返回，回到开始拖动的位置继续播放
    if ([self.leftTimeLabel.text isEqualToString:@"00:00"]) {
        // 写上这句会立即回到原来的位置，不写就过一秒再回去
        // [self updateProgressInfo];
        return;
    }
    
    // 2.2 如果没有拖动到最后面结束位置，就修改当前播放时间
    self.player.currentTime = self.player.duration * self.progressSlider.value;
    // 滑动到对应的位置
    [self updateProgressInfo];
}

// 点击进度条
- (void)sliderClick:(UITapGestureRecognizer *)tap{
    // 1、获取点击的位置
    CGPoint location = [tap locationInView:tap.view];
    
    // 2、获取点击位置在slider长度中占据的比例
    CGFloat ratio = location.x / self.progressSlider.bounds.size.width;
    
    // 3、改变当前播放的时间
    self.player.currentTime = self.player.duration * ratio;
    
    // 4、更新进度信息
    [self updateProgressInfo];
}

#pragma mark - <AVAudioPlayerDelegate>
// 播放结束时调用
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag{
    // 播放结束自动下一曲
    if (flag) {
        [self nextMusic];
    }
}

#pragma mark - <UIScrollViewDelegate>
- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
    CGFloat ratio = 1 - scrollView.contentOffset.x / scrollView.bounds.size.width;
    self.iconView.alpha = ratio;
    self.lrcLabel.alpha = ratio;
}

#pragma mark - 监听远程事件
- (void)remoteControlReceivedWithEvent:(UIEvent *)event{
    // 使用subtype
    switch (event.subtype) {
        case UIEventSubtypeRemoteControlPlay:
            [self startPlayingMusic];
            break;
            
        case UIEventSubtypeRemoteControlPause:
            [self pause];
            break;
            
        case UIEventSubtypeRemoteControlNextTrack:
            [self nextMusic];
            break;
            
        case UIEventSubtypeRemoteControlPreviousTrack:
            [self previousMuisic];
            break;
            
        default:
            break;
    }
}
@end
